package org.example.study4;

/**
 * 使用单独的锁对象
 */
// 展示了 使用自定义锁对象保护静态变量 的线程同步机制。
// 虽然 count 是静态变量（类级别），但通过 共享同一个实例的锁对象，代码确保了线程安全，最终结果严格等于预期的 10 万。
public class Demo_405 {
    public static void main(String[] args) throws InterruptedException {
        // 初始化累加对象（仅一个实例）
        Counter405 counter = new Counter405(); // 所有线程共享同一个 Counter405 实例

        // 创建两个线程操作同一个实例的累加方法
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                counter.increase(); // 调用同步方法
            }
        });

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                counter.increase(); // 同上
            }
        });

        // 启动线程
        t1.start();
        t2.start();

        // 等待线程结束
        t1.join();
        t2.join();

        // 输出结果（必为 10 万）
        System.out.println("count = " + counter.count);
    }
}


class Counter405 {
    public static int count = 0; // 静态变量，类级别共享

    // 自定义锁对象（实例级别）
    Object locker = new Object(); // 锁对象与实例绑定

    /**
     * 累加方法（使用自定义锁对象同步）
     */
    public void increase() {
        synchronized (locker) { // 锁定当前实例的 locker 对象
            count++; // 原子操作（在同步保护下）
        }
    }
}


// 运行：count = 100000
//原因：所有线程共享同一 locker 对象，同步块串行执行 count++。

/*
1. 锁对象的作用域
locker 是实例变量：每个 Counter405 实例有自己的 locker 对象。
线程共享同一实例：在 Demo_405 的 main 方法中，仅创建了一个 Counter405 实例（counter），因此两个线程共享同一个 locker 对象。
锁对象唯一性：所有线程使用相同的 locker 对象，保证同步有效。

2. 静态变量与锁的匹配
静态变量 count：属于类级别，所有实例共享。
锁对象为实例级别：若创建多个 Counter405 实例（如 counter 和 counter1），每个实例的 locker 不同，此时锁失效，导致线程不安全。
当前代码的安全性：因仅有一个实例，locker 唯一，锁有效。*/


/*总结
核心设计：通过共享同一实例的锁对象，保护静态变量的线程安全。
适用场景：当所有线程操作同一实例时，实例级别的锁可保护类级别变量。
注意事项：若存在多个实例，需使用类级别锁或静态锁对象。
体现知识点：锁对象的作用域需与共享变量的访问范围一致，否则可能引发线程安全问题。*/